﻿#include "mainwindow.h"
#include <QVBoxLayout>
#include <QRandomGenerator>
#include <QList>

// 初始化共享资源和信号量
QSemaphore semaphore(0);  // 初始值为0，表示资源不可用
QList<int> sharedData;    // 共享数据列表
QMutex mutex;             // 保护共享数据的互斥锁

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    // 创建界面元素
    startButton = new QPushButton("Start Threads", this);
    statusLabel = new QLabel("Status: Waiting", this);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(startButton);
    layout->addWidget(statusLabel);

    QWidget *centralWidget = new QWidget(this);
    centralWidget->setLayout(layout);
    setCentralWidget(centralWidget);

    // 连接按钮点击信号到槽函数
    connect(startButton, &QPushButton::clicked, this, &MainWindow::startThreads);
}

MainWindow::~MainWindow()
{
    for (auto thread : threads) {
        thread->quit();
        thread->wait();
        delete thread;
    }
}

void MainWindow::startThreads()
{
    if (!threads.isEmpty()) return;

    // 启动消费者线程
    for (int i = 0; i < 3; ++i) {
        ConsumerThread *thread = new ConsumerThread(i + 1, this);
        threads.append(thread);
        connect(thread, &ConsumerThread::dataConsumed, this, &MainWindow::updateStatus);
        thread->start();
    }

    // 模拟生产者线程添加数据
    for (int i = 0; i < 10; ++i) {
        int value = QRandomGenerator::global()->bounded(100);

        // 加锁保护共享数据
        mutex.lock();
        sharedData.append(value);
        mutex.unlock();

        // 释放一个信号量，表示有一个资源可用
        semaphore.release();

        // 更新状态
        statusLabel->setText("Status: Produced value " + QString::number(value));
        QThread::msleep(5); // 模拟生产延迟
    }
}

void MainWindow::updateStatus(int threadId, int value)
{
    statusLabel->setText(QString("Thread %1 consumed value %2").arg(threadId).arg(value));
}


void ConsumerThread::run()
{
    while (true) {
        // 获取一个信号量，等待资源可用
        semaphore.acquire();

        // 加锁保护共享数据
        mutex.lock();
        if (!sharedData.isEmpty()) {
            int value = sharedData.takeFirst();
            mutex.unlock();

            // 处理数据
            emit dataConsumed(threadId, value);

            QThread::msleep(10); // 模拟处理延迟
        } else {
            mutex.unlock();
        }
    }
}
